layui.define(["jquery", "element", "layer", "laypage", "laytpl"], function(exports){
    var $ = layui.jquery;
    var element = layui.element;
    var layer = layui.layer;
    var laypage = layui.laypage;
    var laytpl = layui.laytpl;
    var x = {};
    
    function toFormData(data)
    {
        var fd = new FormData();
        for(var key in data){
            fd.append(key, data[key]);
        }
        return fd;
    }
    
    function contain(string, element)
    {
        var theList = string.split(",");
        for(var i = 0;i < theList.length;i++){
            if(theList[i] == element){
                return true;
            }
        }
        return false;
    }
    
    x.localStorageName = "fileSelected";
    
    x.getUnique = function()
    {
        var d = new Date();
        var temp = Math.random() + "";
        return "g_" + d.getTime() + "_" + temp.substr(2);
    };

    x.post = function(url, data, successCallback, failCallback)
    {
        function success(response)
        {
            if(response.ok == true && response.status == 200){
                response.json().then(function(json){
                    successCallback(json);
                });
            }
        }
        
        function fail(response)
        {
            failCallback(response);
        }
        
        fetch(url, {method: "post", body: data}).then(success).catch(fail);
    };
    
    x.xhrOnProgress = function(fun)
    {
        return function(){
            var xhr = $.ajaxSettings.xhr();
            xhr.upload.onprogress = fun;
            return xhr;
        };
    };
    
    x.getFileSize = function(i)
    {
        var KB = 1024;
        var MB = KB * 1024;
        var GB = MB * 1024;
        var value = 0;
        var unit = "";
        if(i < KB){
            value = i;
            unit = "Byte";
        }
        else if(i < MB){
            value = i / KB;
            unit = "KB";
        }
        else if(i < GB){
            value = i / MB;
            unit = "MB";
        }
        else{
            value = i / GB;
            unit = "GB";
        }
        value = value.toFixed(2);
        return {
            "value": value,
            "unit": unit
        };
    };
    
    x.getFileExt = function(name)
    {
        var position = name.lastIndexOf(".");
        if(position <= 0){
            return "";
        }
        var ext = name.substr(position).toLowerCase();
        return ext;
    };
    
    x.isVideo = function(name)
    {
        var ext = x.getFileExt(name);
        if(ext == ".mp4" || ext == ".flv" || ext == ".avi" || ext == ".mkv"){
            return true;
        }
        return false;
    };
    
    x.isImage = function(name)
    {
        var ext = x.getFileExt(name);
        if(ext == ".jpg" || ext == ".jpeg" || ext == ".png" || ext == ".gif"){
            return true;
        }
        return false;
    };
    
    x.isMp4 = function(name)
    {
        var ext = x.getFileExt(name);
        if(ext == ".mp4"){
            return true;
        }
        return false;
    };

    x.isBlob = function(url)
    {
        return url.indexOf("blob:") >= 0;
    };
    
    x.getBaseName = function(data)
    {
        var pos = data.lastIndexOf('.');
        return data.substring(0, pos);
    };
    
    x.getMapLength = function(map)
    {
        return Object.keys(map).length;
    };
    
    x.reSort = function(map)
    {
        var list = [];
        layui.each(map, function(index, json){
            var object = JSON.parse(json);
            list[object.addSort] = object;
        });
        var i = 0;
        layui.each(list, function(index, object){
            if(object != undefined){
                object.addSort = i++;
                layui.data(x.localStorageName, {key: object.id, value: JSON.stringify(object)});
            }
        });
    };
    
    x.setImageShow = function(id, isSetBoxWidth)
    {
        var box = $("#" + id);
        var count = parseInt(box.attr("count"));
        var margin = parseInt(box.attr("margin"));
        var width = parseInt(box.attr("width"));
        var widthWithBorder = width + 2;
        var height = parseInt(box.attr("height"));
        var minCount = Math.min(count, box.find(".dry-image-show").length);
        var boxWidth = (widthWithBorder + 2 * margin) * minCount;
        box.find(".dry-image-show").each(function(){
            var src = $(this).attr("src");
            var css = {
                "width": width,
                "height": height,
                "margin": margin,
                "background-image": `url('${src}')`,
                "border": "1px solid #009688",
                "background-size": "contain",
                "background-repeat": "no-repeat",
                "background-position": "center center",
                "float": "left",
                "position": "relative"
            };
            $(this).css(css);
        });
        if(isSetBoxWidth){
            box.css("width", boxWidth);
            box.parent().css("width", boxWidth);
        }
    };

    x.setImageWidthHeight = function(file, callback)
    {
        var imgTag = new Image();
        imgTag.src = window.URL.createObjectURL(file);
        imgTag.onload = function(){
            callback(imgTag.width, imgTag.height);
        };
    };
    
    x.makeRandOssObjectName = function(timestamp)
    {
        var result = getDateTimeData(timestamp);
        return result.Y + "/" + result.m + "/" + result.d + "/" + result.H + "" + result.i + "" + result.s + "-" + mtRand(100000, 999999);
    };
    
    x.progress = function(instance, index, event)
    {
        instance.config.temp.rate[index].end = time();
        var rate = instance.config.temp.rate[index];
        var span = rate.end - rate.start;
        var m = 1000 * event.loaded / span;
        var temp = x.getFileSize(m);
        var r = temp.value + " " + temp.unit + "/S";
        var tr = $('#upload-' + index);
        tr.find("td.rate").html(r);
        tr.find("td.status").html("上传中");
        var percent = (event.loaded * 100 / event.total).toFixed(2).toString() + "%";
        element.progress('f-' + index, percent);
    };
    
    x.getPrefix = function(file)
    {
        var prefix = 'file';
        if(x.isImage(file.name)){
            prefix = 'image';
        }
        else if(x.isVideo(file.name)){
            prefix = 'video';
        }
        return prefix;
    };

    x.getPoster = function(file)
    {
        var prefix = x.getPrefix(file);
        var map = {
            "image": window.URL.createObjectURL(file),
            "video": "/images/video.png",
            "file": "/images/file.png"
        };
        return map[prefix];
    };
    
    x.getFileShowImage = function(domain, item)
    {
        var image = "/images/file.png";
        if(x.isVideo(item.dry_object)){
            image = "/images/video.png";
        }
        else if(x.isImage(item.dry_object)){
            image = domain + "/" + item.dry_object;
        }
        return image;
    };
    
    x.setNameRule = function(instance, nameRule, index, file)
    {
        var ossConfig = instance.config.temp.ossConfig;
        var prefix = x.getPrefix(file);
        if(nameRule == "raw"){
            instance.config.data.key = ossConfig.dir + prefix + "/raw/" + "${filename}";
        }
        else if(nameRule == "rand"){
            instance.config.data.key = ossConfig.dir + prefix + "/" + x.makeRandOssObjectName(ossConfig.timestamp) + x.getFileExt(file.name);
        }
        /**/
        var tr = $('#upload-' + index);
        var temp = instance.config.data;
        temp["x:prefix"] = prefix;
        temp["x:name"] = tr.find("td.name").find("input").val();
        temp["x:vw"] = 0;
        temp["x:vh"] = 0;
        if(x.isVideo(file.name)){
            var e = $$("v" + index);
            temp["x:vw"] = parseInt(e.videoWidth);
            temp["x:vh"] = parseInt(e.videoHeight);
        }
        instance.config.data = temp;
    };
    
    x.compress = function(isCompress, oldFile, compressSuccess)
    {
        if(isCompress && x.isImage(oldFile.name) && oldFile.size > 1024 * 1024){
            new Compressor(oldFile, {
                quality: 0.7,
                success(result){
                    compressSuccess(result);
                },
                error(err){
                    console.log(err.message);
                }
            });
        }
        else{
            compressSuccess(oldFile);
        }
    };
    
    x.before = function(url, instance)
    {
        function success(json)
        {
            var data = json.data;
            var temp = {
                "success_action_status": 200,
                "OSSAccessKeyId": data.OSSAccessKeyId,
                "key": data.dir + "${filename}",
                "policy": data.policy,
                "signature": data.signature,
                "callback": data.callback,
                "x:domain": data.host,
                "x:vw": 0,
                "x:vh": 0
            };
            instance.config.data = temp;
            instance.config.url = data.host;
            instance.config.temp.ossConfig = data;
        }
        
        x.post(url, toFormData({}), success, function(){});
    };
    
    x.bodyAddVideo = function(index, file)
    {
        var id = "v" + index;
        var src = window.URL.createObjectURL(file);
        $("body").append(`<video src='${src}' class='layui-hide' id='${id}'>`);
    };
    
    x.done = function(response, index)
    {
        var temp = $("#fileId");
        if(temp.val() == ""){
            temp.val(response.data.id);
        }
        else{
            var list = temp.val().split(',');
            list.push(response.data.id);
            temp.val(list.join(','));
        }
        /**/
        var tr = $('#upload-' + index);
        tr.find("td.status").html('<span style="color:#5FB878;">上传成功</span>');
        tr.find("td.operate").html('');
    };
    
    x.error = function(index)
    {
        var tr = $('#upload-' + index);
        tr.find("td.status").html('<span style="color:#FF5722;">上传失败</span>');
        tr.find("td.operate").find('.upload-reupload-button').removeClass('layui-hide');
    };
    
    x.submit = function()
    {
        $("#submit").click(function(){
            function success(json)
            {
                layer.msg("操作成功", function(){
                    window.location.reload();
                });
            }
            
            if($("#fileId").val() == ""){
                layer.msg("请上传文件后再提交");
                return false;
            }
            var data = {
                "category": $("#category").val(),
                "fileId": $("#fileId").val()
            };
            x.post("", toFormData(data), success, function(){});
        });
    };
    
    x.getScaleWidthHeight = function(width1, height1, width2, height2)
    {
        width1 = parseInt(width1);
        height1 = parseInt(height1);
        width2 = parseInt(width2);
        height2 = parseInt(height2);
        if(width2 <= width1 && height2 <= height1){
            return {"width": width2, "height": height2};
        }
        var widthRate = width1 / width2;
        var heightRate = height1 / height2;
        var target1 = {"width": width1, "height": parseInt(height2 * widthRate)};
        var target2 = {"width": parseInt(width2 * heightRate), "height": height1};
        if(target1.width <= width1 && target1.height <= height1){
            return target1;
        }
        return target2;
    };
    
    x.doPlay = function()
    {
        function runPlay(id)
        {
            var prefix = $(id).attr("prefix");
            var width = $(id).attr("width");
            var height = $(id).attr("height");
            var src = $(id).attr("playSrc");
            var target = x.getScaleWidthHeight(window.innerWidth - 20, window.innerHeight - 20, width, height);
            var html = "";
            if(prefix == "video"){
                var bool1 = x.isMp4(src) && width >= 0;
                var bool2 = x.isBlob(src);
                if(!(bool1 || bool2)){
                    window.open("iina://open?full_screen=0&pip=0&enqueue=0&new_window=0&url=" + encodeURIComponent(src));
                    return false;
                }
                html = `<div style="text-align:center;padding-top:5px;"><video src="${src}" id="video" width="${target.width}" height="${target.height}" controls="true" autoplay="true" style="outline:none;"></div>`;
            }
            else if(prefix == "image"){
                html = `<div style="text-align:center;padding-top:5px;"><img src="${src}" width="${target.width}" height="${target.height}"/></div>`;
            }
            else{
                window.open(src);
                return false;
            }
            var target = x.getScaleWidthHeight(window.innerWidth - 20, window.innerHeight - 20, width, height);
            layer.open({
                type: 1,
                title: false,
                closeBtn: 0,
                shadeClose: true,
                area: [(target.width + 10) + "px", (target.height + 10) + "px"],
                content: html
            });
        }
        
        $("body").on("click", ".doPlay", function(e){
            runPlay($(this).attr("ref"));
            e.stopPropagation();
        });
    };
    
    x.fileList = function(id, count, limit, jumpCallback, url)
    {
        laypage.render({
            elem: 'page' + id,
            count: count,
            curr: 1,
            limit: limit,
            theme: '#1E9FFF',
            layout: ['count', 'prev', 'page', 'next', 'limit', 'refresh', 'skip'],
            jump: function(obj, first){
                jumpCallback(obj.curr, obj.limit, id, url);
            }
        });
    };
    
    x.getOssDomain = function()
    {
        return OSS_DOMAIN;
    };
    
    x.loadData = function(page, limit, categoryId, url)
    {
        function success(json)
        {
            html(json, categoryId);
        }

        function html(json, categoryId)
        {
            var theData = {
                list: json.data,
                domain: x.getOssDomain()
            };
            laytpl(x.categoryAccordionList).render(theData, function(html){
                $("#imageShowBox-" + categoryId).html(html);
                x.setImageShow("imageShowBox-" + categoryId, false);
                restore();
            });
        }

        function restore()
        {
            var map = layui.data(x.localStorageName);
            layui.each(map, function(key, value){
                var id = "#file" + key;
                x.select(id);
            });
        }
        
        var data = {
            "page": page,
            "limit": limit,
            "categoryId": categoryId
        };
        x.post(url, toFormData(data), success, null);
    };
    
    x.select = function(id)
    {
        $(id).find(".file-selected").removeClass("layui-hide");
    };
    
    x.doOverOutClick = function()
    {
        $("body").on("mouseover", ".doOverOutClick", function(e){
            $(this).css("border-color", "#FF5722");
            $(this).find(".play-button").removeClass("layui-hide");
        });
        /**/
        $("body").on("mouseout", ".doOverOutClick", function(e){
            $(this).css("border-color", "#009688");
            $(this).find(".play-button").addClass("layui-hide");
        });
        /**/
        $("body").on("click", ".doOverOutClick", function(e){
            var temp = $(this).find(".file-selected");
            var textarea = temp.find("textarea");
            var html = textarea.html();
            var rs = JSON.parse(html);
            if(temp.hasClass("layui-hide")){
                temp.removeClass("layui-hide");
                var map = layui.data(x.localStorageName);
                /*把之前的数据全部重新排序 start*/
                x.reSort(map);
                /*把之前的数据全部重新排序 end*/
                rs.addSort = x.getMapLength(map);
                layui.data(x.localStorageName, {key: rs.id, value: JSON.stringify(rs)});
            }
            else{
                temp.addClass("layui-hide");
                layui.data(x.localStorageName, {key: rs.id, remove: true});
                var map = layui.data(x.localStorageName);
                /*把数据全部重新排序 start*/
                x.reSort(map);
                /*把数据全部重新排序 end*/
            }
        });
    };
    
    x.doMove = function(url)
    {
        function success()
        {
            layui.data(x.localStorageName, null);
            window.location.reload();
        }
        
        var map = layui.data(x.localStorageName);
        if(!x.getMapLength(map)){
            layer.msg("没有文件被选中");
            return false;
        }
        var temp = $(".layui-colla-content.layui-show");
        if(temp.length != 1){
            layer.msg("当前没有展开的分类");
            return false;
        }
        var list = [];
        layui.each(map, function(key, value){
            list.push(key);
        });
        var data = {
            "idIn": list.join(","),
            "categoryId": temp.attr("data")
        };
        x.post(url, toFormData(data), success, function(){});
    };

    x.doDelete = function(url)
    {
        function ok()
        {
            function success()
            {
                layer.msg("已删除", function(){
                    layui.data(x.localStorageName, null);
                    window.location.reload();
                });
            }

            x.post(url, toFormData(data), success, function(){});
        }

        function cancel()
        {
            layer.msg("已取消");
        }

        var map = layui.data(x.localStorageName);
        if(!x.getMapLength(map)){
            layer.msg("没有文件被选中");
            return false;
        }
        var list = [];
        layui.each(map, function(key, value){
            list.push(key);
        });
        var data = {
            "idIn": list.join(",")
        };
        layer.confirm('确定删除吗?', {btn:['确定','取消']}, ok, cancel);
    };

    x.doBlur = function(url, id, name)
    {
        var data = {
            "id": id,
            "name": name
        };
        x.post(url, toFormData(data), function(){}, function(){});
    };
    
    x.doSelectButton = function(name, iframeUrl)
    {
        var id = "#" + name;
        /*打开之前先记录选中 start*/
        var temp = $(id).parent().find("textarea").html();
        if(temp != ""){
            temp = JSON.parse(temp);
            layui.each(temp, function(index, rs){
                layui.data(x.localStorageName, {key: rs.id, value: JSON.stringify(rs)});
            });
        }
        /*打开之前先记录选中 end*/
        layer.open({
            type: 2,
            title: "选择后请直接关闭本窗口",
            shadeClose: false,
            shade: 0.8,
            area: ['95%', '95%'],
            maxmin: true,
            content: iframeUrl,
            cancel: function(index, layero){
                var map = layui.data(x.localStorageName);
                layui.data(x.localStorageName, null);
                var list = [];
                var listData = [];
                var idList = [];
                layui.each(map, function(index, rs){
                    var temp = JSON.parse(rs);
                    list[temp.addSort] = rs;
                    listData[temp.addSort] = temp;
                });
                layui.each(list, function(index, rs){
                    var temp = JSON.parse(rs);
                    idList.push(temp.id);
                });
                $(id).val(idList.join(","));
                $(id).parent().find("textarea").html(JSON.stringify(listData));
                var json = {
                    domain: x.getOssDomain(),
                    list: listData
                };
                /**/
                laytpl(x.fileSelectItem).render(json, function(html){
                    var theId = $(id).parent().find("div.box").attr("id");
                    $("#" + theId).html(html);
                    x.setImageShow(theId, false);
                });
                /**/
            }
        });
    };
    
    /*
        1.文件在列表和详情页的显示
        2.dry模组调用的
        3.target 指一个有dryMergeRequest类的div标签
        4.json 表示合并后的所有数据
        5.iframeUrl 表示图片数字点击后需要打开的网页地址
        6.full 是否全部显示
        7.value 文件id字符串
    */
    x.fileShow = function(target, json, iframeUrl, full, value)
    {
        var allList = json.data.list;
        var list = [];
        var map = {};
        for(var i = 0;i < allList.length;i++){
            var item = allList[i];
            map["id" + item.id] = item;
        }
        var valueList = value.split(",");
        for(var i = 0;i < valueList.length;i++){
            var temp = valueList[i];
            if(map["id" + temp]){
                list.push(map["id" + temp]);
            }
        }
        /**/
        if(list.length == 0){
            return "";
        }
        /**/
        var total = list.length;
        var code = '';
        if(full == 1){
            code = x.fileShowForShow;
        }
        else{
            code = x.fileShowForIndex;
            list = [list[0]];
        }
        /**/
        var d = {
            domain: x.getOssDomain(),
            list: list,
            total: total,
            iframeUrl: iframeUrl,
            idIn: value
        };
        laytpl(code).render(d, function(html){
            $(target).html(html);
            if(full == 1){
                x.setImageShow("imageShowBox", false);
                x.doPlay();
            }
        });
    };
    
    x.doFileFullShow = function()
    {
        $("body").on("click", ".doFileFullShow", function(){
            layer.open({
                type: 2,
                title: "文件列表",
                shadeClose: false,
                shade: 0.8,
                area: ['99%', '99%'],
                maxmin: true,
                content: $(this).attr("url")
            });
            return false;
        });
    };
    
    /*添加文件时每一行的模板*/
    x.tr = `
        <tr id="upload-{{ d.index }}">
            <td>
                <div id="imageShowBox-{{ d.index }}" count="1" margin="0" width="100" height="100">
                    <div class="dry-image-show doPlay" src="{{ d.url }}" ref="#playInfo{{ d.index }}"></div>
                    <div class="clear"></div>
                </div>
                <div class="playInfo layui-hide" id="playInfo{{ d.index }}" prefix="{{ d.prefix }}" width="0" height="0" playSrc="{{ d.playUrl }}"></div>
            </td>
            <td class="width"></td>
            <td class="height"></td>
            <td>{{ d.file.sizeText }}</td>
            <td style="max-width:100px;word-break:break-all;">{{ d.file.name }}</td>
            <td class="name" width="150"><input type="text" class="layui-input" value="{{ d.name }}"></td>
            <td><div class="layui-progress" lay-showPercent="true" lay-filter="f-{{ d.index }}"><div class="layui-progress-bar" lay-percent="0%"></div></div></td>
            <td class="rate"></td>
            <td class="status">等待上传</td>
            <td class="operate">
                <a href="javascript:void(0);" class="layui-btn layui-btn-xs layui-hide upload-reupload-button">重传</a>
                <a href="javascript:void(0);" class="layui-btn layui-btn-xs layui-btn-danger upload-delete-button">删除</a>
            </td>
        </tr>
    `;
    
    /*文件列表时每一个分类下的文件显示模板*/
    x.categoryAccordionList = `
        {{#
        layui.each(d.list, function(index, item){
        var src = layui.file.getFileShowImage(d.domain, item);
        }}
        <div class="dry-image-show doOverOutClick" id="file{{ item.id }}" src="{{ src }}" playSrc="{{ d.domain }}/{{ item.dry_object }}" width="{{ item.dry_width }}" height="{{ item.dry_height }}" prefix="{{ item.dry_prefix }}">
            <div class="play-button layui-hide doPlay" ref="#file{{ item.id }}"><i class="layui-icon layui-icon-play"></i></div>
            <div class="file-selected layui-hide">
                <span class="layui-badge layui-unselect" style="border-radius:0;">已选中</span>
                <textarea class="layui-hide">{{ JSON.stringify(item) }}</textarea>
            </div>
            <input type="text" class="file-name-input layui-unselect doBlur" value="{{ item.dry_name }}" title="{{ item.dry_name }}" data="{{ item.id }}" onclick="event.stopPropagation();"/>
        </div>
        {{# }); }}
        <div class="clear"></div>
    `;
    
    /*添加编辑时文件选择后的模板*/
    x.fileSelectItem = `
    {{#
    d.domain = layui.file.getOssDomain();
    layui.each(d.list, function(index, item){
    var src = layui.file.getFileShowImage(d.domain, item);
    }}
        <div class="dry-image-show doPlay" src="{{ src }}" playSrc="{{ d.domain }}/{{ item.dry_object }}" id="file{{ item.id }}" width="{{ item.dry_width }}" height="{{ item.dry_height }}" prefix="{{ item.dry_prefix }}" ref="#file{{ item.id }}">
            <input type="text" class="file-name-input" value="{{ item.dry_name }}" title="{{ item.dry_name }}" onfocus="this.blur()"/>
        </div>
    {{# }); }}
    <div class="clear"></div>
    `;
    
    /*文件在数据列表时的显示*/
    x.fileShowForIndex = `
    {{#
    layui.each(d.list, function(index, item){
    var src = layui.file.getFileShowImage(d.domain, item);
    var id = layui.file.getUnique();
    }}
    <div class="data-file-list pointer doPlay" id="{{ id }}" style="background-image:url('{{ src }}');" playSrc="{{ d.domain }}/{{ item.dry_object }}" width="{{ item.dry_width }}" height="{{ item.dry_height }}" prefix="{{ item.dry_prefix }}" ref="#{{ id }}" title="{{ item.dry_name }}">
        {{#
        if(d.total >= 2){
        }}
        <div>
            <span class="layui-badge layui-unselect pointer doFileFullShow" url="{{ d.iframeUrl }}?idIn={{ d.idIn }}">{{ d.total }}</span>
        </div>
        {{# } }}
    </div>
    {{# }); }}
    `;
    
    /*文件在数据查看时的显示*/
    x.fileShowForShow = `
    <div id="imageShowBox" count="50" margin="10" width="150" height="150" style="margin-left:-10px;">  
    ${x.fileSelectItem}
    </div>
    `;

    exports('file', x);
});